import {
  ArrayCompact,
  ArrayFlatten,
  ArrayJoin,
  ArrayUnique,
  Count,
  CountA,
  CountAll,
} from './array';
import type { FormulaFunc } from './common';
import { FunctionName } from './common';
import {
  CreatedTime,
  DateAdd,
  Datestr,
  DatetimeDiff,
  DatetimeFormat,
  DatetimeParse,
  Day,
  FromNow,
  Hour,
  IsAfter,
  IsBefore,
  IsSame,
  LastModifiedTime,
  Minute,
  Month,
  Now,
  Second,
  Timestr,
  ToNow,
  Today,
  WeekNum,
  Weekday,
  Workday,
  WorkdayDiff,
  Year,
} from './date-time';
import { And, Blank, FormulaError, If, IsError, Not, Or, Switch, Xor } from './logical';
import {
  Abs,
  Average,
  Ceiling,
  Even,
  Exp,
  Floor,
  Int,
  Log,
  Max,
  Min,
  Mod,
  Odd,
  Power,
  Round,
  RoundDown,
  RoundUp,
  Sqrt,
  Sum,
  Value,
} from './numeric';
import { AutoNumber, RecordId, TextAll } from './system';
import {
  Concatenate,
  EncodeUrlComponent,
  Find,
  Left,
  Len,
  Lower,
  Mid,
  RegExpReplace,
  Replace,
  Rept,
  Right,
  Search,
  Substitute,
  T,
  Trim,
  Upper,
} from './text';

// eslint-disable-next-line @typescript-eslint/naming-convention
export const FUNCTIONS: Record<FunctionName, FormulaFunc> = {
  // Numeric
  [FunctionName.Sum]: new Sum(),
  [FunctionName.Average]: new Average(),
  [FunctionName.Max]: new Max(),
  [FunctionName.Min]: new Min(),
  [FunctionName.Round]: new Round(),
  [FunctionName.RoundUp]: new RoundUp(),
  [FunctionName.RoundDown]: new RoundDown(),
  [FunctionName.Ceiling]: new Ceiling(),
  [FunctionName.Floor]: new Floor(),
  [FunctionName.Even]: new Even(),
  [FunctionName.Odd]: new Odd(),
  [FunctionName.Int]: new Int(),
  [FunctionName.Abs]: new Abs(),
  [FunctionName.Sqrt]: new Sqrt(),
  [FunctionName.Power]: new Power(),
  [FunctionName.Exp]: new Exp(),
  [FunctionName.Log]: new Log(),
  [FunctionName.Mod]: new Mod(),
  [FunctionName.Value]: new Value(),

  // Text
  [FunctionName.Concatenate]: new Concatenate(),
  [FunctionName.Find]: new Find(),
  [FunctionName.Search]: new Search(),
  [FunctionName.Mid]: new Mid(),
  [FunctionName.Left]: new Left(),
  [FunctionName.Right]: new Right(),
  [FunctionName.Replace]: new Replace(),
  [FunctionName.RegExpReplace]: new RegExpReplace(),
  [FunctionName.Substitute]: new Substitute(),
  [FunctionName.Lower]: new Lower(),
  [FunctionName.Upper]: new Upper(),
  [FunctionName.Rept]: new Rept(),
  [FunctionName.Trim]: new Trim(),
  [FunctionName.Len]: new Len(),
  [FunctionName.T]: new T(),
  [FunctionName.EncodeUrlComponent]: new EncodeUrlComponent(),

  // Logical
  [FunctionName.If]: new If(),
  [FunctionName.Switch]: new Switch(),
  [FunctionName.And]: new And(),
  [FunctionName.Or]: new Or(),
  [FunctionName.Xor]: new Xor(),
  [FunctionName.Not]: new Not(),
  [FunctionName.Blank]: new Blank(),
  [FunctionName.Error]: new FormulaError(),
  [FunctionName.IsError]: new IsError(),

  // DateTime
  [FunctionName.Today]: new Today(),
  [FunctionName.Now]: new Now(),
  [FunctionName.Year]: new Year(),
  [FunctionName.Month]: new Month(),
  [FunctionName.WeekNum]: new WeekNum(),
  [FunctionName.Weekday]: new Weekday(),
  [FunctionName.Day]: new Day(),
  [FunctionName.Hour]: new Hour(),
  [FunctionName.Minute]: new Minute(),
  [FunctionName.Second]: new Second(),
  [FunctionName.FromNow]: new FromNow(),
  [FunctionName.ToNow]: new ToNow(),
  [FunctionName.DatetimeDiff]: new DatetimeDiff(),
  [FunctionName.Workday]: new Workday(),
  [FunctionName.WorkdayDiff]: new WorkdayDiff(),
  [FunctionName.IsSame]: new IsSame(),
  [FunctionName.IsAfter]: new IsAfter(),
  [FunctionName.IsBefore]: new IsBefore(),
  [FunctionName.DateAdd]: new DateAdd(),
  [FunctionName.Datestr]: new Datestr(),
  [FunctionName.Timestr]: new Timestr(),
  [FunctionName.DatetimeFormat]: new DatetimeFormat(),
  [FunctionName.DatetimeParse]: new DatetimeParse(),
  [FunctionName.CreatedTime]: new CreatedTime(),
  [FunctionName.LastModifiedTime]: new LastModifiedTime(),

  // Array
  [FunctionName.CountAll]: new CountAll(),
  [FunctionName.CountA]: new CountA(),
  [FunctionName.Count]: new Count(),
  [FunctionName.ArrayJoin]: new ArrayJoin(),
  [FunctionName.ArrayUnique]: new ArrayUnique(),
  [FunctionName.ArrayFlatten]: new ArrayFlatten(),
  [FunctionName.ArrayCompact]: new ArrayCompact(),

  // System
  [FunctionName.TextAll]: new TextAll(),
  [FunctionName.RecordId]: new RecordId(),
  [FunctionName.AutoNumber]: new AutoNumber(),
};
